<?php
final class Slog
{
	const VERSION = '0.1a';
	
	static protected $_view;
	static protected $_config;
	static protected $_router;
	static protected $_request;
	static protected $_response;
	static protected $_session;
	static protected $_dispatcher;
	
	static public function run()
	{
		//ob_start('ob_tidyhandler');
		//ob_start('ob_gzhandler');
		
		// Registramos el autoload
		spl_autoload_register(array('Slog','autoload'));
		
		// Cargamos la configuración
		Slog::config()->init();
		
		// Establece las constantes definidas en la configuración
		Slog::constants();
		
		// Configuramos la base de datos
		Slog::database();
		
		// Inicializamos la sesión
		Slog::session()->init();
		
		// Procesamos la petición
		Slog::request()->init();
		// Inicializamos el router
		Slog::router()->init();
		// Inicializamos el manejador de respuesta
		Slog::response()->init();
		// Inicializamos el dispatcher
		Slog::dispatcher()->init();
		// Ejecutamos
		Slog::dispatcher()->exec();
		// Procesamos la salida
		Slog::response()->out();
	}
	
	static public function autoload($class)
	{
		// Tratamos de cargar de la librería general
		$file = SLOG_DIR_LIB . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
		if (is_file($file)) {
			include_once($file);
			return;
		}
		
		foreach (explode(';', SLOG_DIR_APPS) as $appdir) {
			// Tratamos de cargar desde la librería específica de las aplicaciones
			$file = $appdir . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
			if (is_file($file)) {
				include_once($file);
				return;
			}
			
			// Buscamos entre los modelos
			$file = $appdir . DIRECTORY_SEPARATOR . 'models' . DIRECTORY_SEPARATOR . $class . '.php';
			if (is_file($file)) {
				include_once($file);
				return;
			}
		}
		
		// No se encontró la clase
		throw new Exception('La clase no existe: ' . $class);
	}
	
	static private function database()
	{
		$config = Slog::config()->getArray('database');
		switch (strtolower($config['driver'])) {
			case 'mysql':
				Slog_Db_Driver_MySQL::connect($config);
				Slog_Db_Table::setDriver(new Slog_Db_Driver_Mysql());
				break;
		}
	}
	
	static private function constants()
	{
		// Constantes de usuario
		foreach (Slog::config()->getArray('constant') as $cname=>$cvalue) {
			$cname = strtoupper(str_replace('.','_',$cname));
			define($cname, $cvalue);
		}
	}
	
	/**
	 * Devuelve la instancia del manejador de vistas
	 *
	 * @return	Slog_View
	 */
	static public function view()
	{
		return self::$_view === null ? (self::$_view = new Slog_View()) : self::$_view;
	}

	/**
	 * 
	 * @return	Slog_Config
	 */
	static public function config()
	{
		return self::$_config === null ? (self::$_config = new Slog_Config()) : self::$_config;
	}
	

	/**
	 * 
	 *
	 * @return Slog_Session
	 */
	static public function session()
	{
		return self::$_session === null ? (self::$_session = new Slog_Session()) : self::$_session;
	}
	
	/**
	 * Devuelve una instancia del Router
	 *
	 * @return	Slog_Router
	 */
	static public function router()
	{
		return self::$_router === null ? (self::$_router = new Slog_Router()) : self::$_router;
	}
	
	/**
	 * Devuelve el dispatcher de controladores
	 *
	 * @return	Slog_Controller_Dispatcher
	 */
	static public function dispatcher()
	{
		return self::$_dispatcher === null ? (self::$_dispatcher = new Slog_Controller_Dispatcher()) : self::$_dispatcher;
	}
	
	/**
	 * Devuelve el manejador de petición
	 *
	 * @return	Slog_Controller_Request
	 */
	static public function request()
	{
		return self::$_request === null ? (self::$_request = new Slog_Controller_Request()) : self::$_request;
	}
	
	/**
	 * Manejador de respuesta
	 *
	 * @return	Slog_Controller_Response
	 */
	static public function response()
	{
		return self::$_response === null ? (self::$_response = new Slog_Controller_Response()) : self::$_response;
	}
	
}


// Constantes con los directorios del sistema
define('SLOG_DIR_ROOT', realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..');
define('SLOG_DIR_APP', SLOG_DIR_ROOT . DIRECTORY_SEPARATOR . 'app');
define('SLOG_DIR_CONFIG', SLOG_DIR_ROOT . DIRECTORY_SEPARATOR . 'config');
define('SLOG_DIR_LIB', SLOG_DIR_ROOT . DIRECTORY_SEPARATOR . 'lib');

// Obtenemos la URI base
$document_root = $_SERVER['DOCUMENT_ROOT'];
$script_directory = dirname($_SERVER['SCRIPT_FILENAME']);
$base_uri = '/' . str_replace(DIRECTORY_SEPARATOR, '/', substr($script_directory, strlen($document_root)));
define('SLOG_URI_BASE', $base_uri);
